package com.hrpc.watcher;

import com.hrpc.NettyBootStrapInitializer;
import com.hrpc.discovery.Register;
import com.hrpc.hRpcBootStarp;
import com.hrpc.loadbalancer.LoadBalancer;
import io.netty.channel.Channel;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;

import java.net.InetSocketAddress;
import java.util.List;
import java.util.Map;

    public class UpAndDownWatcher implements Watcher {
    @Override
    public void process(WatchedEvent watchedEvent) {
        if (watchedEvent.getType() == Event.EventType.NodeChildrenChanged){
            System.out.println(watchedEvent.getPath()+"----------子节点发生了变化");
            //要重新拉取服务列表
            Register register = hRpcBootStarp.getInstance().getRegister();
            String serviceName = getServiceName(watchedEvent.getPath());
            List<InetSocketAddress> addresses = register.lookup(serviceName,hRpcBootStarp.getInstance().getConfiguration().getGroup());
            for (InetSocketAddress address : addresses) {
                //1.新增节点会在address中，不在CHANNEL_CACHE中
                if (!hRpcBootStarp.CHANNEL_CACHE.containsKey(address)){
                    //根据地址建立连接，并缓存
                    try {
                        Channel channel = NettyBootStrapInitializer.getBootstrap().connect(address).sync().channel();
                        hRpcBootStarp.CHANNEL_CACHE.put(address,channel);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
                //2.处理下线的节点，可能会在CHANNEL_CACHE，但是不在address
                for (Map.Entry<InetSocketAddress,Channel> entry : hRpcBootStarp.CHANNEL_CACHE.entrySet()){
                    if (!addresses.contains(entry.getKey())){
                        hRpcBootStarp.CHANNEL_CACHE.remove(entry.getKey());
                    }
                }
                //获取负载均衡器。进行重新的loadBalance
                LoadBalancer loadBalancer = hRpcBootStarp.getInstance().getConfiguration().getLoad_balancer();
                loadBalancer.reLoadBalance(serviceName,addresses);
            }
        }
    }

    private String getServiceName(String path){
        String[] split = path.split("/");
        return split[split.length-1];
    }

}
